ASA DataFest Q&A

Prof Nathan Taback will drop in to answer questions you might have.

A quick tour of the ISSC

There are three important parts of the ISSC (well 4, if you count the most important part, YOU!)

Mini-challenge

Your mission, should you choose to accept it, is to complete a mini-data visualisation challenge by the end of the day.

1. Set up GitHub

You can definitely do this challenge even if you haven’t sorted out your GitHub yet, but I’d strongly recommend making this one of your ISSC goals. More information in the first 6 Sigma Sunday newsletter. You may wish to create a repository to store this mini-project in called ‘ISSC’ or ‘TidyTuesday’ folder. I have one called ‘ISSC’ with the files from the this AND the two previous TidyTuesday & Talks.

2. Create an R Markdown document

Or it could be an R Script, but I prefer RMDs, like what this is written in. It is perfect for when you want your code, outputs and commentary to all be together.

3. Install/load packages

If you haven’t installed tidyverse yet, you will need that package for today. It has dplyr and ggplot in it.

4. Load the data for this week.

There is more than one way to get this data. I’m going to use the tidytuesdayR package becasue I installed it last week. Choose the way that is right for you from these options.

5. Take a look at the data

glimpse(vb_matches)
Rows: 76,756
Columns: 65
$ circuit               <chr> "AVP", "AVP", "AVP", "AVP", "AVP", "AVP", "AVP", "AVP", "AVP", "AVP", "…
$ tournament            <chr> "Huntington Beach", "Huntington Beach", "Huntington Beach", "Huntington…
$ country               <chr> "United States", "United States", "United States", "United States", "Un…
$ year                  <dbl> 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002, 2002,…
$ date                  <date> 2002-05-24, 2002-05-24, 2002-05-24, 2002-05-24, 2002-05-24, 2002-05-24…
$ gender                <chr> "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "M", "…
$ match_num             <dbl> 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, …
$ w_player1             <chr> "Kevin Wong", "Brad Torsone", "Eduardo Bacil", "Brent Doble", "Albert H…
$ w_p1_birthdate        <date> 1972-09-12, 1975-01-14, 1971-03-11, 1970-01-03, 1970-05-04, 1974-07-21…
$ w_p1_age              <dbl> 29.69473, 27.35661, 31.20329, 32.38604, 32.05476, 27.84120, 31.47981, 2…
$ w_p1_hgt              <dbl> 79, 78, 74, 78, 75, 75, 78, 77, 75, 79, 73, 79, 78, 77, 73, 77, 79, 78,…
$ w_p1_country          <chr> "United States", "United States", "Brazil", "United States", "United St…
$ w_player2             <chr> "Stein Metzger", "Casey Jennings", "Fred Souza", "Karch Kiraly", "Jeff …
$ w_p2_birthdate        <date> 1972-11-17, 1975-07-10, 1972-05-13, 1960-11-03, 1972-08-03, 1972-02-01…
$ w_p2_age              <dbl> 29.51403, 26.87201, 30.02875, 41.55236, 29.80424, 30.30801, 28.25188, N…
$ w_p2_hgt              <dbl> 75, 75, 79, 74, 80, 77, 78, 79, 75, 76, 76, 75, NA, 78, 73, 74, 75, 74,…
$ w_p2_country          <chr> "United States", "United States", "Brazil", "United States", "United St…
$ w_rank                <chr> "1", "16", "24", "8", "5", "12", "13", "4", "3", "14", "22", "6", "26",…
$ l_player1             <chr> "Chuck Moore", "Mark Paaluhi", "Adam Jewell", "David Swatik", "Adam Rob…
$ l_p1_birthdate        <date> 1973-08-18, 1971-03-08, 1975-06-24, 1973-02-14, 1976-01-25, 1979-02-10…
$ l_p1_age              <dbl> 28.76386, 31.21150, 26.91581, 29.27036, 26.32717, 23.28268, 30.23956, 2…
$ l_p1_hgt              <dbl> 76, 75, 77, 76, 73, NA, 75, 75, 68, 75, 77, 74, 78, 73, 79, 73, 78, 74,…
$ l_p1_country          <chr> "United States", "United States", "United States", "United States", "Un…
$ l_player2             <chr> "Ed Ratledge", "Nick Hannemann", "Collin Smith", "Mike Mattarocci", "Ji…
$ l_p2_birthdate        <date> 1976-12-16, 1972-01-12, 1975-05-26, 1969-10-05, 1978-03-26, 1969-05-30…
$ l_p2_age              <dbl> 25.43463, 30.36277, 26.99521, 32.63244, 24.16153, 32.98289, 30.13826, 2…
$ l_p2_hgt              <dbl> 80, 78, 76, 80, 75, 76, 81, 77, 77, 74, 73, 73, 72, 73, 71, 78, 75, 79,…
$ l_p2_country          <chr> "United States", "United States", "United States", "United States", "Un…
$ l_rank                <chr> "32", "17", "9", "25", "28", "21", "20", "29", "30", "19", "11", "27", …
$ score                 <chr> "21-18, 21-12", "21-16, 17-21, 15-10", "21-18, 21-18", "21-16, 21-15", …
$ duration              <time> 00:33:00, 00:57:00, 00:46:00, 00:44:00, 01:08:00, 00:55:00, 00:46:00, …
$ bracket               <chr> "Winner's Bracket", "Winner's Bracket", "Winner's Bracket", "Winner's B…
$ round                 <chr> "Round 1", "Round 1", "Round 1", "Round 1", "Round 1", "Round 1", "Roun…
$ w_p1_tot_attacks      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p1_tot_kills        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p1_tot_errors       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p1_tot_hitpct       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p1_tot_aces         <dbl> 1, 0, 0, 0, 1, 0, 0, 0, 1, 2, 4, 0, 1, 0, 0, 2, 1, 1, 1, 1, 1, 0, 1, 1,…
$ w_p1_tot_serve_errors <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p1_tot_blocks       <dbl> 7, 4, 2, 3, 0, 0, 0, 0, 2, 3, 0, 3, 4, 0, 2, 1, 4, 7, 0, 0, 2, 0, 0, 4,…
$ w_p1_tot_digs         <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p2_tot_attacks      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p2_tot_kills        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p2_tot_errors       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p2_tot_hitpct       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p2_tot_aces         <dbl> 2, 4, 0, 0, 0, 0, 0, 0, 0, 4, 0, 1, 2, 0, 0, 0, 2, 0, 1, 0, 0, 0, 0, 2,…
$ w_p2_tot_serve_errors <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ w_p2_tot_blocks       <dbl> 0, 0, 4, 0, 6, 0, 0, 3, 3, 1, 5, 0, 0, 1, 0, 1, 0, 0, 1, 5, 2, 4, 5, 0,…
$ w_p2_tot_digs         <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p1_tot_attacks      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p1_tot_kills        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p1_tot_errors       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p1_tot_hitpct       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p1_tot_aces         <dbl> 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0,…
$ l_p1_tot_serve_errors <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p1_tot_blocks       <dbl> 0, 2, 1, 2, 0, 0, 0, 0, 0, 1, 9, 1, 1, 1, 1, 0, 3, 0, 0, 3, 1, 2, 1, 0,…
$ l_p1_tot_digs         <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p2_tot_attacks      <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p2_tot_kills        <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p2_tot_errors       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p2_tot_hitpct       <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p2_tot_aces         <dbl> 0, 0, 0, 2, 0, 0, 0, 3, 0, 0, 0, 0, 1, 4, 0, 0, 1, 0, 0, 0, 0, 1, 2, 0,…
$ l_p2_tot_serve_errors <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…
$ l_p2_tot_blocks       <dbl> 1, 0, 0, 0, 1, 0, 0, 0, 0, 2, 0, 0, 0, 1, 1, 1, 0, 5, 1, 1, 2, 0, 0, 0,…
$ l_p2_tot_digs         <dbl> NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA,…

6. Wrangle the data

This data is pretty clean and tidy but we might want to play with a few things. I wanted to make seperate datasets so I could look at data by individual players across all their matches and look at general data about the players and the match.

# make a dataset with just information about the match
match_info <- vb_clean %>% 
  select(-contains("p1"), -contains("p2"), -contains("player")) %>% 
  separate(score, into=c("score_set1", "score_set2", "score_set3"), sep = ",")
Expected 3 pieces. Missing pieces filled with `NA` in 52319 rows [1, 3, 4, 7, 8, 9, 10, 12, 15, 16, 17, 18, 21, 23, 24, 25, 26, 27, 28, 29, ...].

7. Create at least 3 exploratory plots/summary statistics.

You might find the Cookbook for R graphics from the BBC helpful, as well as the resources in 6 Sigma Sunday #2 on using dplyr and ggplot.

Explore!

What is the usual difference between scores in set 1 of a match?

Explore!

What proportion of matches go to the third set?

Explore!

Win rates by players?

Explore!

Are players getting any taller?

8. Choose one plot to improve and use/include the following:

I’ve chosen the height/gender/age.

The average height of Canadian men is 5’ 10" (70 inches) and the average height of Canadian women is 5’ 4" (64 inches). Source: https://www.cbc.ca/news/health/height-growth-canada-1.3695398

## model with gender interaction
summary(lm(hgt~birthdate*gender, data = winrate_filter))

Call:
lm(formula = hgt ~ birthdate * gender, data = winrate_filter)

Residuals:
    Min      1Q  Median      3Q     Max 
-10.958  -1.638  -0.057   1.815   9.846 

Coefficients:
                    Estimate Std. Error t value Pr(>|t|)    
(Intercept)        7.476e+01  1.405e-01 532.202  < 2e-16 ***
birthdate          7.673e-05  2.209e-05   3.474 0.000518 ***
genderW           -4.894e+00  2.089e-01 -23.422  < 2e-16 ***
birthdate:genderW -3.841e-05  3.121e-05  -1.230 0.218593    
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 2.594 on 4287 degrees of freedom
Multiple R-squared:  0.4916,    Adjusted R-squared:  0.4913 
F-statistic:  1382 on 3 and 4287 DF,  p-value: < 2.2e-16

A title and subtitle AND caption acknowledging the data source + your name

Labelled axes

An appropriate colour palette

Explicitly use a theme (check out this list of defaults included with ggplot or get the ggtheme package)

BONUS: Add an annotation

9. Save the plot using ggsave().

If you run ?ggsave, it will tell you that “ggsave() is a convenient function for saving a plot. It defaults to saving the last plot that you displayed, using the size of the current graphics device. It also guesses the type of graphics device from the extension.”

ggsave("vb_heights_birthyear_gender.png")
Saving 7 x 7 in image

BONUS BONUS!: Cowplot

10. Share the plot!

Share the plot and link to your commented code with all your working in #portfolio-building with a 1–2 sentence explanation by the end of Tuesday May 19 (bonus if you share it on Twitter with #TidyTuesday). Our ISSC Tweeps are on this list. Message me if you want to be added!

Thanks everyone!

Please make sure you fill out the weekly check-in by Thursday at 11:30 pm ET.

LS0tCnRpdGxlOiAnVGlkeVR1ZXNkYXk6IEJlYWNoIHZvbGxleWJhbGwnCmF1dGhvcjogIkxpemEgQm9sdG9uIgpkYXRlOiAnMjAyMC0wNS0xOScKb3V0cHV0OgogIHBkZl9kb2N1bWVudDogZGVmYXVsdAogIGh0bWxfbm90ZWJvb2s6IGRlZmF1bHQKICBodG1sX2RvY3VtZW50OgogICAgZGZfcHJpbnQ6IHBhZ2VkCnVybGNvbG9yOiAjNEIwMDgyCi0tLQoKLSBUaGlzIHNlc3Npb24gd2lsbCBiZSByZWNvcmRlZCBhbmQgcHV0IHVwIG9uIFtQYXN0IGV2ZW50c10oaHR0cHM6Ly91dG9yb250by5zaGFyZXBvaW50LmNvbS9zaXRlcy9BcnRTY2ktU1RBL0lTU0MvU2l0ZVBhZ2VzL1Bhc3QtZXZlbnRzLmFzcHgpCi0gQ2xpY2sgdGhlIHN0YWNrZWQgbGluZXMgYXQgdGhlIHRvcCBsZWZ0IG9mIHRoaXMgcGFuZWwgdG8gb3BlbiBhIGhlbGZwdWwgbmF2aWdhdGlvbiBwYW5lCi0gUmVtZWJlciB0byBmaWxsIG91dCB0aGUgW3dlZWtseSBjaGVjay1pbl0oaHR0cHM6Ly9mb3Jtcy5vZmZpY2UuY29tL1BhZ2VzL1Jlc3BvbnNlUGFnZS5hc3B4P2lkPUpzS3FlQU12VFV1UU43UnRWc1ZTRU9LSFVVM1N6QUpKaG1PS2pKaERXRXBVTUZoWFVWRTRXVU5CTnpOS1VFaENOREJCUzFRd04wdFNOQzR1KSBieSBUaHVyc2RheSBhdCAxMTozMCBwbSBFVC4gCgojIEFTQSBEYXRhRmVzdCBRJkEKClByb2YgTmF0aGFuIFRhYmFjayB3aWxsIGRyb3AgaW4gdG8gYW5zd2VyIHF1ZXN0aW9ucyB5b3UgbWlnaHQgaGF2ZS4KCiMgQSBxdWljayB0b3VyIG9mIHRoZSBJU1NDCgpUaGVyZSBhcmUgdGhyZWUgaW1wb3J0YW50IHBhcnRzIG9mIHRoZSBJU1NDICh3ZWxsIDQsIGlmIHlvdSBjb3VudCB0aGUgbW9zdCBpbXBvcnRhbnQgcGFydCwgWU9VISkKCi0gKipTbGFjayoqIGlzIHdoZXJlIGFsbCB0aGUgcmVhbC10aW1lIGNoYXR0aW5nIGFuZCByZXNvdXJjZSBzaGFyaW5nIGhhcHBlbnMuCi0gWyoqU2hhcmVQb2ludCoqXShodHRwczovL3V0b3JvbnRvLnNoYXJlcG9pbnQuY29tL3NpdGVzL0FydFNjaS1TVEEvSVNTQy9TaXRlUGFnZXMvSVNTQy1Ib21lLmFzcHgpIGlzIGFuIGFyY2hpdmUgZm9yIHRoZSBjb21tdW5pdHkgd2hlcmUgeW91IGNhbiBmaW5kIHRoZSBwcmV2aW91cyBbNiBTaWdtYSBTdW5kYXkgbmV3c2xldHRlcnNdKGh0dHBzOi8vdXRvcm9udG8uc2hhcmVwb2ludC5jb20vc2l0ZXMvQXJ0U2NpLVNUQS9JU1NDL1NpdGVQYWdlcy82JUNGJTgzLVN1bmRheXMuYXNweCksIHJlc291cmNlcyBhbmQgcmVjb3JkaW5ncyBmcm9tIFtwYXN0IGV2ZW50c10oaHR0cHM6Ly91dG9yb250by5zaGFyZXBvaW50LmNvbS9zaXRlcy9BcnRTY2ktU1RBL0lTU0MvU2l0ZVBhZ2VzL1Bhc3QtZXZlbnRzLmFzcHgpLCBhcyB3ZWxsIGFzIGEgcmFuZ2Ugb2YgcmVzb3VyY2VzIGluIHRoZSBbR2VuZXJhbCBSZXNvdXJjZXMgbGlicmFyeV0oaHR0cHM6Ly91dG9yb250by5zaGFyZXBvaW50LmNvbS9zaXRlcy9BcnRTY2ktU1RBL0lTU0MvR2VuZXJhbCUyMFJlc291cmNlcy9Gb3Jtcy9BbGxJdGVtcy5hc3B4KS4KLSBbKipBU0EgRGF0YUZlc3RAVW9mVCBzaXRlKipdKGh0dHBzOi8vZGF0YWZlc3R1b2Z0LmdpdGh1Yi5pby8pIGZvciByZWdpc3RyYXRpb24sIHNvbWUgc3VnZ2VzdGVkIHJlc29ydWNlcyBhbmQgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCB0aGUgY29tcGV0aXRpb24uIGh0dHBzOi8vZGF0YWZlc3R1b2Z0LmdpdGh1Yi5pby8gCgojIE1pbmktY2hhbGxlbmdlCgpZb3VyIG1pc3Npb24sIHNob3VsZCB5b3UgY2hvb3NlIHRvIGFjY2VwdCBpdCwgaXMgdG8gY29tcGxldGUgYSBtaW5pLWRhdGEgdmlzdWFsaXNhdGlvbiBjaGFsbGVuZ2UgYnkgdGhlIGVuZCBvZiB0aGUgZGF5LgoKIyMgMS4gU2V0IHVwIEdpdEh1YgoKWW91IGNhbiBkZWZpbml0ZWx5IGRvIHRoaXMgY2hhbGxlbmdlIGV2ZW4gaWYgeW91IGhhdmVuJ3Qgc29ydGVkIG91dCB5b3VyIEdpdEh1YiB5ZXQsIGJ1dCBJJ2Qgc3Ryb25nbHkgcmVjb21tZW5kIG1ha2luZyB0aGlzIG9uZSBvZiB5b3VyIElTU0MgZ29hbHMuIE1vcmUgaW5mb3JtYXRpb24gaW4gW3RoZSBmaXJzdCA2IFNpZ21hIFN1bmRheSBuZXdzbGV0dGVyXShodHRwczovL3V0b3JvbnRvLnNoYXJlcG9pbnQuY29tL3NpdGVzL0FydFNjaS1TVEEvSVNTQy9TaXRlUGFnZXMvNi5hc3B4KS4gWW91IG1heSB3aXNoIHRvIGNyZWF0ZSBhIHJlcG9zaXRvcnkgdG8gc3RvcmUgdGhpcyBtaW5pLXByb2plY3QgaW4gY2FsbGVkICdJU1NDJyBvciAnVGlkeVR1ZXNkYXknIGZvbGRlci4gSSBoYXZlIG9uZSBjYWxsZWQgWydJU1NDJ10oaHR0cHM6Ly9naXRodWIuY29tL2VsYjAvSVNTQykgd2l0aCB0aGUgZmlsZXMgZnJvbSB0aGUgdGhpcyBBTkQgdGhlIHR3byBwcmV2aW91cyBUaWR5VHVlc2RheSAmIFRhbGtzLgoKIyMgMi4gQ3JlYXRlIGFuIFIgTWFya2Rvd24gZG9jdW1lbnQgCk9yIGl0IGNvdWxkIGJlIGFuIFIgU2NyaXB0LCBidXQgSSBwcmVmZXIgUk1EcywgbGlrZSB3aGF0IHRoaXMgaXMgd3JpdHRlbiBpbi4gSXQgaXMgcGVyZmVjdCBmb3Igd2hlbiB5b3Ugd2FudCB5b3VyIGNvZGUsIG91dHB1dHMgYW5kIGNvbW1lbnRhcnkgdG8gYWxsIGJlIHRvZ2V0aGVyLgoKYGBge3IsIG91dC53aWR0aCA9ICI1MCUiLCBlY2hvPUZBTFNFfQprbml0cjo6aW5jbHVkZV9ncmFwaGljcygiaW1hZ2VzL3JtYXJrZG93bl93aXphcmRzLnBuZyIpCgojIE5vdGljZSBob3cgSSBhbSB1c2luZyBhIGNvZGUgY2h1bmsgdG8gbG9hZCBhbiBpbWFnZSBhbmQgaGlkaW5nIHRoaXMgY29kZSB3aXRoIGVjaG89RkFMU0UKYGBgCgojIyAzLiBJbnN0YWxsL2xvYWQgcGFja2FnZXMKCklmIHlvdSBoYXZlbid0IGluc3RhbGxlZCBgdGlkeXZlcnNlYCB5ZXQsIHlvdSB3aWxsIG5lZWQgdGhhdCBwYWNrYWdlIGZvciB0b2RheS4gSXQgaGFzIGBkcGx5cmAgYW5kIGBnZ3Bsb3RgIGluIGl0LgpgYGB7ciwgb3V0LndpZHRoID0gIjIwJSIsIGVjaG89RkFMU0V9CmtuaXRyOjppbmNsdWRlX2dyYXBoaWNzKCJpbWFnZXMvdGlkeXZlcnNlX2NlbGVzdGlhbC5wbmciKQpgYGAKCmBgYHtyLCBtZXNzYWdlPUZBTFNFfQojaW5zdGFsbC5wYWNrYWdlcygidGlkeXZlcnNlIikKI2luc3RhbGwucGFja2FnZXMoImx1YnJpZGF0ZSIpCiNpbnN0YWxsLnBhY2thZ2VzKCJnZ3RoZW1lcyIpCmxpYnJhcnkoInRpZHl2ZXJzZSIpCmxpYnJhcnkoImx1YnJpZGF0ZSIpCmxpYnJhcnkoImdndGhlbWVzIikKCiMgTm90aWNlIGhvdyBJIGFtIHVzaW5nIG1lc3NhZ2U9RkFMU0UgaW4gdGhpcyBjaHVuayB0byBzdXBwcmVzcyB0aGUgaW5mb3JtYXRpb24gCiMgYWJvdXQgbG9hZGluZyB0aWR5dmVyc2UuIEkgZG9uJ3Qgd2hhdCB0aGlzIGFzIHBhcnQgb2YgbXkgZmluYWwgZG9jdW1lbnQgYmVjYXVzZSAKIyBpdCBpc24ndCB2ZXJ5IHByZXR0eS4gQWx3YXlzIHN1cHByZXNzIHdpdGggY2FyZSB0aG91Z2gsCiMgYW5kIGlmIHlvdSdyZSBydW5uaW5nIGluIHRvIGlzc3VlcywgbWFrZSBzdXJlIHRvIGNoZWNrIHRoaXMuCmBgYAoKCiMjIDQuIExvYWQgdGhlIGRhdGEgZm9yIHRoaXMgd2Vlay4KClRoZXJlIGlzIG1vcmUgdGhhbiBvbmUgd2F5IHRvIGdldCB0aGlzIGRhdGEuIEknbSBnb2luZyB0byB1c2UgdGhlIGB0aWR5dHVlc2RheVJgIHBhY2thZ2UgYmVjYXN1ZSBJIGluc3RhbGxlZCBpdCBsYXN0IHdlZWsuIENob29zZSB0aGUgd2F5IHRoYXQgaXMgcmlnaHQgZm9yIHlvdSBmcm9tIFt0aGVzZSBvcHRpb25zLl0oaHR0cHM6Ly9naXRodWIuY29tL3Jmb3JkYXRhc2NpZW5jZS90aWR5dHVlc2RheS9ibG9iL21hc3Rlci9kYXRhLzIwMjAvMjAyMC0wNS0xOS9yZWFkbWUubWQjZ2V0LXRoZS1kYXRhLWhlcmUpCgpgYGB7ciwgY2FjaGU9VFJVRX0KdHVlc2RhdGEgPC0gdGlkeXR1ZXNkYXlSOjp0dF9sb2FkKCcyMDIwLTA1LTE5JykKdmJfbWF0Y2hlcyA8LSB0dWVzZGF0YSR2Yl9tYXRjaGVzCnJtKHR1ZXNkYXRhKSAjIHJlbW92ZSB0aGUgb3JpZ2luYWwgZmlsZSBiZWNhdXNlIHdlIGRvbid0IG5lZWQgaXQgYW55IG1vcmUKYGBgCgojIyA1LiBUYWtlIGEgbG9vayBhdCB0aGUgZGF0YQpgYGB7cn0KZ2xpbXBzZSh2Yl9tYXRjaGVzKQpgYGAKCiMjIDYuIFdyYW5nbGUgdGhlIGRhdGEKVGhpcyBkYXRhIGlzIHByZXR0eSBjbGVhbiBhbmQgdGlkeSBidXQgd2UgbWlnaHQgd2FudCB0byBwbGF5IHdpdGggYSBmZXcgdGhpbmdzLiBJIHdhbnRlZCB0byBtYWtlIHNlcGVyYXRlIGRhdGFzZXRzIHNvIEkgY291bGQgbG9vayBhdCBkYXRhIGJ5IGluZGl2aWR1YWwgcGxheWVycyBhY3Jvc3MgYWxsIHRoZWlyIG1hdGNoZXMgYW5kIGxvb2sgYXQgZ2VuZXJhbCBkYXRhIGFib3V0IHRoZSBwbGF5ZXJzIGFuZCB0aGUgbWF0Y2guCgpgYGB7cn0KdmJfY2xlYW4gPC0gdmJfbWF0Y2hlcyAlPiUgCiAgcm93aWRfdG9fY29sdW1uKHZhciA9ICJtYXRjaF9JRCIpICAgICMgbWFrZSBhbiBJRCBjb2x1bW5zCgpsX3BsYXllcjEgPC0gdmJfY2xlYW4gJT4lIAogIHNlbGVjdChtYXRjaF9JRCwgZ2VuZGVyLCBjb250YWlucygibF9wMSIpLCBjb250YWlucygibF9wbGF5ZXIxIikpICU+JSAKICByZW5hbWUoc2V0TmFtZXMobmFtZXMoLiksIGdzdWIoImxfcDFfIiwgIiIsIG5hbWVzKC4pKSkpICU+JSAKICByZW5hbWUocGxheWVyID0gImxfcGxheWVyMSIpICU+JSAKICBzZWxlY3QobWF0Y2hfSUQsIHBsYXllciwgZXZlcnl0aGluZygpKSAlPiUgICMgdHJ5IHJlbG9jYXRlKCkgaW4gZHBseXIgMS4wLjAgCiAgbXV0YXRlKHN0YXR1cyA9ICJMb3N0IiwgcGxheWVyX251bSA9IDEpCgpsX3BsYXllcjIgPC0gdmJfY2xlYW4gJT4lIAogIHNlbGVjdChtYXRjaF9JRCwgZ2VuZGVyLCBjb250YWlucygibF9wMiIpLCBjb250YWlucygibF9wbGF5ZXIyIikpICU+JSAKICByZW5hbWUoc2V0TmFtZXMobmFtZXMoLiksIGdzdWIoImxfcDJfIiwgIiIsIG5hbWVzKC4pKSkpICU+JSAKICByZW5hbWUocGxheWVyID0gImxfcGxheWVyMiIpICU+JSAKICBzZWxlY3QobWF0Y2hfSUQsIHBsYXllciwgZXZlcnl0aGluZygpKSAlPiUgCiAgICBtdXRhdGUoc3RhdHVzID0gIkxvc3QiLCBwbGF5ZXJfbnVtID0gMikKCndfcGxheWVyMSA8LSB2Yl9jbGVhbiAlPiUgCiAgc2VsZWN0KG1hdGNoX0lELCBnZW5kZXIsIGNvbnRhaW5zKCJ3X3AxIiksIGNvbnRhaW5zKCJ3X3BsYXllcjEiKSkgJT4lIAogIHJlbmFtZShzZXROYW1lcyhuYW1lcyguKSwgZ3N1Yigid19wMV8iLCAiIiwgbmFtZXMoLikpKSkgJT4lIAogIHJlbmFtZShwbGF5ZXIgPSAid19wbGF5ZXIxIikgJT4lIAogIHNlbGVjdChtYXRjaF9JRCwgcGxheWVyLCBldmVyeXRoaW5nKCkpICU+JSAKICBtdXRhdGUoc3RhdHVzID0gIldvbiIsIHBsYXllcl9udW0gPSAxKQoKd19wbGF5ZXIyIDwtIHZiX2NsZWFuICU+JSAKICBzZWxlY3QobWF0Y2hfSUQsIGdlbmRlciwgY29udGFpbnMoIndfcDIiKSwgY29udGFpbnMoIndfcGxheWVyMiIpKSAlPiUgCiAgcmVuYW1lKHNldE5hbWVzKG5hbWVzKC4pLCBnc3ViKCJ3X3AyXyIsICIiLCBuYW1lcyguKSkpKSAlPiUgCiAgcmVuYW1lKHBsYXllciA9ICJ3X3BsYXllcjIiKSAlPiUgCiAgc2VsZWN0KG1hdGNoX0lELCBwbGF5ZXIsIGV2ZXJ5dGhpbmcoKSkgJT4lIAogIG11dGF0ZShzdGF0dXMgPSAiV29uIiwgcGxheWVyX251bSA9IDIpCgojIG9uY2UgSSB3cm90ZSB0aGlzIEkgcmVhbGlzZWQgaXQgbWlnaHQgYmUgbmljZSB0byB3cml0ZSBhIGZ1bmN0aW9uIAojIHRoYXQgZG9lcyB0aGVzZSBzaW1pbGFyIHN0ZXBzIGluc3RlYWQuLi5JJ20gbm90IGdvaW5nIHRvIGRvIHRoYXQgdG9kYXksIAojIGJ1dCBsZXQgbWUga25vdyBpZiB5b3UgZ2l2ZSBpdCBhIGdvIQoKcGxheWVyX21hdGNoZXMgPC0gYmluZF9yb3dzKGxfcGxheWVyMSwgbF9wbGF5ZXIyLCB3X3BsYXllcjEsIHdfcGxheWVyMikKCiMgbWFrZSBhIGRhdGFzZXQgd2l0aCBqdXN0IHVuY2hhbmluZyBpbmZvcm1hdGlvbiBhYm91dCBlYWNoIHBsYXllcgpwbGF5ZXJfaW5mbyA8LSBwbGF5ZXJfbWF0Y2hlcyAlPiUgCiAgc2VsZWN0KHBsYXllciwgZ2VuZGVyLCBiaXJ0aGRhdGUsIGhndCwgY291bnRyeSkgJT4lIAogIHVuaXF1ZSgpCgojIG1ha2UgYSBkYXRhc2V0IHdpdGgganVzdCBpbmZvcm1hdGlvbiBhYm91dCB0aGUgbWF0Y2gKbWF0Y2hfaW5mbyA8LSB2Yl9jbGVhbiAlPiUgCiAgc2VsZWN0KC1jb250YWlucygicDEiKSwgLWNvbnRhaW5zKCJwMiIpLCAtY29udGFpbnMoInBsYXllciIpKSAlPiUgCiAgc2VwYXJhdGUoc2NvcmUsIGludG89Yygic2NvcmVfc2V0MSIsICJzY29yZV9zZXQyIiwgInNjb3JlX3NldDMiKSwgc2VwID0gIiwiKQpgYGAKCgojIyA3LiBDcmVhdGUgYXQgbGVhc3QgMyBleHBsb3JhdG9yeSBwbG90cy9zdW1tYXJ5IHN0YXRpc3RpY3MuCgpZb3UgbWlnaHQgZmluZCB0aGUgW0Nvb2tib29rIGZvciBSIGdyYXBoaWNzIGZyb20gdGhlIEJCQ10oaHR0cHM6Ly9iYmMuZ2l0aHViLmlvL3Jjb29rYm9vay8pIGhlbHBmdWwsIGFzIHdlbGwgYXMgdGhlIHJlc291cmNlcyBpbiBbNiBTaWdtYSBTdW5kYXkgIzJdKGh0dHBzOi8vdXRvcm9udG8uc2hhcmVwb2ludC5jb20vc2l0ZXMvQXJ0U2NpLVNUQS9JU1NDL1NpdGVQYWdlcy82JUNGJTgzLVN1bmRheS0tMi5hc3B4KSBvbiB1c2luZyBkcGx5ciBhbmQgZ2dwbG90LgoKIyMjIEV4cGxvcmUhCgpXaGF0IGlzIHRoZSB1c3VhbCBkaWZmZXJlbmNlIGJldHdlZW4gc2NvcmVzIGluIHNldCAxIG9mIGEgbWF0Y2g/CmBgYHtyfQptYXRjaF9pbmZvMiA8LSBtYXRjaF9pbmZvICU+JSAKICBmaWx0ZXIoc2NvcmVfc2V0MSAhPSAiRm9yZmVpdCBvciBvdGhlciIpICU+JSAKICBmaWx0ZXIoIWdyZXBsKCJyZXRpcmVkIiwgc2NvcmVfc2V0MSkpICU+JSAKICByb3d3aXNlKCkgJT4lIAogIG11dGF0ZShkaWZmX3NldDEgPSBhYnMoZXZhbChwYXJzZSh0ZXh0PXNjb3JlX3NldDEpKSkpCgptYXRjaF9pbmZvMiAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gZGlmZl9zZXQxKSkgKwogIGdlb21faGlzdG9ncmFtKGJpbndpZHRoID0gMC45OSkKYGBgCgojIyMgRXhwbG9yZSEKCldoYXQgcHJvcG9ydGlvbiBvZiBtYXRjaGVzIGdvIHRvIHRoZSB0aGlyZCBzZXQ/IAoKYGBge3J9CgptYXRjaF9pbmZvICU+JSAgCiAgbXV0YXRlKHRocmVlX3NldHMgPSBpZmVsc2UoaXMubmEoc2NvcmVfc2V0MyksIEZBTFNFLCBUUlVFKSkgJT4lIAogIHN1bW1hcmlzZShwcm9wXzNfc2V0ID0gbWVhbih0aHJlZV9zZXRzKSkKCmBgYAoKIyMjIEV4cGxvcmUhIAoKV2luIHJhdGVzIGJ5IHBsYXllcnM/CgpgYGB7cn0Kd2lucmF0ZSA8LSBwbGF5ZXJfbWF0Y2hlcyAlPiUgCiAgbXV0YXRlKHdfbCA9IGlmZWxzZShzdGF0dXM9PSJXb24iLCAxLCAwKSkgJT4lIAogIGdyb3VwX2J5KHBsYXllcikgJT4lIAogIHN1bW1hcmlzZShwcm9wX3cgPSBtZWFuKHdfbCksIG1hdGNoZXMgPSBuKCkpICU+JSAKICBsZWZ0X2pvaW4ocGxheWVyX2luZm8sIGJ5ID0gInBsYXllciIpICU+JSAKICBmaWx0ZXIoIWlzLm5hKGhndCkpICU+JSAKICBtdXRhdGUoY291bnRyeV90b3AgPSBmY3RfbHVtcF9uKGNvdW50cnksIG4gPSA1KSkKCnRhYmxlKHdpbnJhdGUkY291bnRyeV90b3ApCgp3aW5yYXRlICU+JSAKICBmaWx0ZXIobWF0Y2hlcyA+PSAxMDApICU+JQogIGdncGxvdChhZXMoeCA9IGhndCwgeSA9IHByb3BfdykpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArCiAgZmFjZXRfd3JhcCh+Z2VuZGVyKSArCiAgZ2VvbV9zbW9vdGgobWV0aG9kPSJsbSIpCiAgCndpbnJhdGUgJT4lIAogIGZpbHRlcihtYXRjaGVzID49IDEwMCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gaGd0LCB5ID0gcHJvcF93LCBjb2xvdXIgPSBjb3VudHJ5X3RvcCwgc2l6ZSA9IG1hdGNoZXMpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuNSkgKwogIGZhY2V0X3dyYXAofmdlbmRlcikKCndpbnJhdGUgJT4lIAogIGZpbHRlcihtYXRjaGVzID49IDEwMCkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gbWF0Y2hlcywgeSA9IHByb3BfdykpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC41KSArCiAgZmFjZXRfd3JhcCh+Z2VuZGVyKQoKYGBgCgoKIyMjIEV4cGxvcmUhCgpBcmUgcGxheWVycyBnZXR0aW5nIGFueSB0YWxsZXI/CgpgYGB7cn0KcGxheWVyX2luZm8gJT4lIAogIGZpbHRlcihiaXJ0aGRhdGU+MTk2MCkgJT4lIAogIGZpbHRlcighaXMubmEoaGd0KSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGJpcnRoZGF0ZSwgeSA9IGhndCkpICsKICBnZW9tX3BvaW50KGFlcyhhbHBoYSA9IDAuNSkpICsKICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIikgKyAKICBmYWNldF93cmFwKH5nZW5kZXIpICsgCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IDY4KSwgY29sb3IgPSAicHVycGxlIikKYGBgCgpgYGB7cn0KcGxheWVyX2luZm8gJT4lIAogIGZpbHRlcihiaXJ0aGRhdGU+MTk2MCkgJT4lIAogIGZpbHRlcighaXMubmEoaGd0KSkgJT4lCiAgZ2dwbG90KGFlcyh4ID0gYmlydGhkYXRlLCBmaWxsPWdlbmRlcikpICsKICBnZW9tX2hpc3RvZ3JhbSgpICsKICBmYWNldF93cmFwKH5nZW5kZXIsIG5yb3c9MikKCnBsYXllcl9pbmZvICU+JSAKICBmaWx0ZXIoYmlydGhkYXRlPjE5NjApICU+JSAKICBmaWx0ZXIoIWlzLm5hKGhndCkpICU+JSAKICBtdXRhdGUoYmlydGhfZGVjYWRlID0gZmxvb3JfZGF0ZShiaXJ0aGRhdGUsIHllYXJzKDEwKSkpICU+JSAKICBncm91cF9ieShiaXJ0aF9kZWNhZGUsIGdlbmRlcikgJT4lIAogIG11dGF0ZShjb3VudCA9IG4oKSkgJT4lIAogIGdncGxvdChhZXMoeCA9IGJpcnRoX2RlY2FkZSwgeSA9IGNvdW50LCBmaWxsID0gZ2VuZGVyKSkgKwogICAgZ2VvbV9iYXIoc3RhdD0iaWRlbnRpdHkiLCBwb3NpdGlvbiA9ICJkb2RnZSIpCmBgYAoKCiMjIDguIENob29zZSBvbmUgcGxvdCB0byBpbXByb3ZlIGFuZCB1c2UvaW5jbHVkZSB0aGUgZm9sbG93aW5nOgoKSSd2ZSBjaG9zZW4gdGhlIGhlaWdodC9nZW5kZXIvYWdlLiAKClRoZSBhdmVyYWdlIGhlaWdodCBvZiBDYW5hZGlhbiBtZW4gaXMgNScgMTAiICg3MCBpbmNoZXMpIGFuZCB0aGUgYXZlcmFnZSBoZWlnaHQgb2YgQ2FuYWRpYW4gd29tZW4gaXMgNScgNCIgKDY0IGluY2hlcykuClNvdXJjZTogaHR0cHM6Ly93d3cuY2JjLmNhL25ld3MvaGVhbHRoL2hlaWdodC1ncm93dGgtY2FuYWRhLTEuMzY5NTM5OAoKYGBge3J9CmNhbl9wb3AgPC0gdGliYmxlKGhndCA9IGMoNzAsIDY0KSwgZ2VuZGVyID0gYygiTSIsICJXIikpCgp3aW5yYXRlX2ZpbHRlciA8LSB3aW5yYXRlICU+JSAKICBmaWx0ZXIoYmlydGhkYXRlPjE5NjApICU+JSAKICBmaWx0ZXIoIWlzLm5hKGhndCkpCgpiYXNlX3Bsb3QgPC0gd2lucmF0ZV9maWx0ZXIgJT4lIAogIGdncGxvdChhZXMoeCA9IGJpcnRoZGF0ZSwgeSA9IGhndCwgY29sb3IgPSBnZW5kZXIpKSArCiAgZ2VvbV9wb2ludChhbHBoYSA9IDAuMjUpICsKICBnZW9tX3Ntb290aChtZXRob2Q9ImxtIiwgZm9ybXVsYSA9IHkgfiB4LCBjb2xvdXIgPSAiYmxhY2siLCBzaXplID0gMS41KSArCiAgZmFjZXRfd3JhcCh+Z2VuZGVyKSArCiAgZ2VvbV9obGluZShhZXMoeWludGVyY2VwdCA9IGhndCksIGNhbl9wb3AsIGNvbG9yID0gImJsYWNrIiwgc2l6ZSA9IDEuNSwgbHR5ID0gImRhc2hlZCIpCmJhc2VfcGxvdAoKIyMgbW9kZWwgZm9yIGFsbApzdW1tYXJ5KGxtKGhndH5iaXJ0aGRhdGUsIGRhdGEgPSB3aW5yYXRlX2ZpbHRlcikpCgojIyBtb2RlbCB3aXRoIGdlbmRlciBpbnRlcmFjdGlvbgpzdW1tYXJ5KGxtKGhndH5iaXJ0aGRhdGUqZ2VuZGVyLCBkYXRhID0gd2lucmF0ZV9maWx0ZXIpKQoKYGBgCgoKIyMjIEEgdGl0bGUgYW5kIHN1YnRpdGxlIEFORCBjYXB0aW9uIGFja25vd2xlZGdpbmcgdGhlIGRhdGEgc291cmNlICsgeW91ciBuYW1lCmBgYHtyfQpwMSA8LSBiYXNlX3Bsb3QgKwogIGxhYnModGl0bGUgPSAiSGVpZ2h0cyBieSBkYXRlIG9mIGJpcnRoIGZvciBiZWFjaCB2b2xsZXliYWxsIHBsYXllcnMiLAogICAgICAgICBzdWJ0aXRsZSA9ICJSZXN0cmljdGVkIHRvIGNvbXBldGl0b3JzIGluIHRoZSBGSVZCIGFuZCBBVlAgdG91cm5hbWVudHMgYW5kIGJvcm4gc2luY2UgMTk2MCIsCiAgICAgICBjYXB0aW9uID0gIlNvdXJjZTogQmlnVGltZVN0YXRzIHZpYSAjVGlkeVR1ZXNkYXlcbiBDaGFydCBieTogQGxpemFfYm9sdG9uIikKCnAxCmBgYAoKIyMjIExhYmVsbGVkIGF4ZXMKYGBge3J9CiMgTmV3IGZhY2V0IGxhYmVsIG5hbWVzIGZvciBnZW5kZXIgKGRvbid0IHdhbnQganVzdCBsZXR0ZXJzKQpnZW5kZXIubGFicyA8LSBjKCJNZW4iLCAiV29tZW4iKQpuYW1lcyhnZW5kZXIubGFicykgPC0gYygiTSIsICJXIikKCnAyIDwtIHAxICsgCiAgZmFjZXRfZ3JpZCh+Z2VuZGVyLCBsYWJlbGxlciA9IGxhYmVsbGVyKGdlbmRlciA9IGdlbmRlci5sYWJzKSkgKwogIHhsYWIoIkRhdGUgb2YgYmlydGgiKSArCiAgeWxhYigiSGVpZ2h0IChpbmNoZXMpIikKcDIKCmBgYAoKIyMjIEFuIGFwcHJvcHJpYXRlIGNvbG91ciBwYWxldHRlCmBgYHtyfQojIEdldCBteSBnZW5kZXIgY29sb3VycyBpZiB5b3Ugd2FudCB0aGVtCnNvdXJjZSgiaHR0cHM6Ly9naXN0LmdpdGh1YnVzZXJjb250ZW50LmNvbS9lbGIwL2FlNTU4MDlkYmM2MTBhNTBmYmE3YmI1Mzc3NDk3Y2Q2L3Jhdy8xYjE3ZGRiOTJkNDVmNWNhZWU3MzRmZjJmZjhlMTc3NGZlZDNlYzkxL3N1ZmZyYWdlLWNvbG91cnMuUiIpCgpwMyA8LSBwMiArCiAgc2NhbGVfY29sb3JfbWFudWFsKHZhbHVlcyA9IHJldihzdWZmcmFnZV9jb2xzKSkKcDMKCmBgYAoKIyMjIEV4cGxpY2l0bHkgdXNlIGEgdGhlbWUgKGNoZWNrIG91dCB0aGlzIGxpc3Qgb2YgZGVmYXVsdHMgaW5jbHVkZWQgd2l0aCBnZ3Bsb3Qgb3IgZ2V0IHRoZSBnZ3RoZW1lIHBhY2thZ2UpCmBgYHtyfQpwNCA8LSBwMyArCiAgdGhlbWVfZml2ZXRoaXJ0eWVpZ2h0KCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dCgpKSArCiAgeGxhYigiRGF0ZSBvZiBiaXJ0aCIpICsKICB5bGFiKCJIZWlnaHQgKGluY2hlcykiKQpwNAogCmBgYAoKIyMjIEJPTlVTOiBBZGQgYW4gYW5ub3RhdGlvbgpgYGB7cn0KCnA1IDwtIHA0ICsKICBhbm5vdGF0ZSgidGV4dCIsIGxhYmVsID0gIkRvdHRlZCBsaW5lcyBzaG93IGF2ZXJhZ2UgY3VycmVudCBoZWlnaHQgb2YgQ2FuYWRpYW5zIiwgeCA9IGFzLkRhdGUoIjE5ODAtMDEtMDEiKSwgeSA9IDY1LCApCnA1Cgphbm5vIDwtIHRpYmJsZSh4MSA9IGFzLkRhdGUoIjE5OTYtMDEtMDEiKSwKICAgICAgICAgICAgICAgICAgIHkxID0gNjUuNiwgCiAgICAgICAgICAgICAgICAgICBnZW5kZXIgPSAiTSIpCgpwNV8yIDwtIHA0ICsgCiAgZ2VvbV90ZXh0KGRhdGEgPSBhbm5vLCBhZXMoeCA9IHgxLCAgeSA9IHkxLCBsYWJlbCA9ICJEb3R0ZWQgbGluZXMgc2hvdyBhdmVyYWdlXG4gY3VycmVudCBoZWlnaHQgb2YgQ2FuYWRpYW5zIiksIHNpemUgPSAzLjUsIGNvbG91ciA9ICJibGFjayIpCgpwNV8yCgpgYGAKCiMjIDkuIFNhdmUgdGhlIHBsb3QgdXNpbmcgZ2dzYXZlKCkuCgpJZiB5b3UgcnVuIGA/Z2dzYXZlYCwgaXQgd2lsbCB0ZWxsIHlvdSB0aGF0ICJgZ2dzYXZlKClgIGlzIGEgY29udmVuaWVudCBmdW5jdGlvbiBmb3Igc2F2aW5nIGEgcGxvdC4gSXQgZGVmYXVsdHMgdG8gc2F2aW5nIHRoZSBsYXN0IHBsb3QgdGhhdCB5b3UgZGlzcGxheWVkLCB1c2luZyB0aGUgc2l6ZSBvZiB0aGUgY3VycmVudCBncmFwaGljcyBkZXZpY2UuIEl0IGFsc28gZ3Vlc3NlcyB0aGUgdHlwZSBvZiBncmFwaGljcyBkZXZpY2UgZnJvbSB0aGUgZXh0ZW5zaW9uLiIKCmBgYHtyfQpnZ3NhdmUoInZiX2hlaWdodHNfYmlydGh5ZWFyX2dlbmRlci5wbmciKQoKZ2dzYXZlKCJ2Yl9oZWlnaHRzX2JpcnRoeWVhcl9nZW5kZXIucG5nIiwgd2lkdGggPSA4LCBoZWlnaHQgPSA0LjUpCgpgYGAKCkJPTlVTIEJPTlVTITogQ293cGxvdAoKYGBge3J9Cm5vX2dlbmRlciA8LSB3aW5yYXRlX2ZpbHRlciAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gYmlydGhkYXRlLCB5ID0gaGd0KSkgKwogIGdlb21fcG9pbnQoYWxwaGEgPSAwLjI1LCBjb2xvciA9ICJibHVlIikgKwogIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBmb3JtdWxhID0geSB+IHgsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxLjUpICsKICAjbGFicyh0aXRsZSA9ICJIZWlnaHRzIGJ5IGRhdGUgb2YgYmlydGggZm9yIGJlYWNoIHZvbGxleWJhbGwgcGxheWVycyIsCiAgIyAgICAgICAgc3VidGl0bGUgPSAiUmVzdHJpY3RlZCB0byBjb21wZXRpdG9ycyBpbiB0aGUgRklWQiBhbmQgQVZQIHRvdXJuYW1lbnRzIGFuZCBib3JuIHNpbmNlIDE5NjAiKSArCiAgdGhlbWVfZml2ZXRoaXJ0eWVpZ2h0KCkgKwogIHRoZW1lKGxlZ2VuZC5wb3NpdGlvbiA9ICJub25lIiwgYXhpcy50aXRsZSA9IGVsZW1lbnRfdGV4dCgpKSArCiAgeGxhYigiRGF0ZSBvZiBiaXJ0aCIpICsKICB5bGFiKCJIZWlnaHQgKGluY2hlcykiKQogIApub19nZW5kZXIKCgpiYXNlX3Bsb3RfMiA8LSB3aW5yYXRlX2ZpbHRlciAlPiUgCiAgZ2dwbG90KGFlcyh4ID0gYmlydGhkYXRlLCB5ID0gaGd0LCBjb2xvciA9IGdlbmRlcikpICsKICBnZW9tX3BvaW50KGFscGhhID0gMC4yNSkgKwogIGdlb21fc21vb3RoKG1ldGhvZD0ibG0iLCBmb3JtdWxhID0geSB+IHgsIGNvbG91ciA9ICJibGFjayIsIHNpemUgPSAxLjUpICsKICBmYWNldF93cmFwKH5nZW5kZXIpICsKICBnZW9tX2hsaW5lKGFlcyh5aW50ZXJjZXB0ID0gaGd0KSwgY2FuX3BvcCwgY29sb3IgPSAiYmxhY2siLCBzaXplID0gMS41LCBsdHkgPSAiZGFzaGVkIikgKwogIGxhYnMoY2FwdGlvbiA9ICJTb3VyY2U6IEJpZ1RpbWVTdGF0cyB2aWEgI1RpZHlUdWVzZGF5XG4gQ2hhcnQgYnk6IExpemEgQm9sdG9uIikgKwogIHRoZW1lX2ZpdmV0aGlydHllaWdodCgpICsKICB0aGVtZShsZWdlbmQucG9zaXRpb24gPSAibm9uZSIsIGF4aXMudGl0bGUgPSBlbGVtZW50X3RleHQoKSkgKwogIGZhY2V0X2dyaWQofmdlbmRlciwgbGFiZWxsZXIgPSBsYWJlbGxlcihnZW5kZXIgPSBnZW5kZXIubGFicykpICsKICB4bGFiKCJEYXRlIG9mIGJpcnRoIikgKwogIHlsYWIoIkhlaWdodCAoaW5jaGVzKSIpICsKICBzY2FsZV9jb2xvcl9tYW51YWwodmFsdWVzID0gcmV2KHN1ZmZyYWdlX2NvbHMpKSArCiAgZ2VvbV90ZXh0KGRhdGEgPSBhbm5vLCBhZXMoeCA9IHgxLCAgeSA9IHkxLCBsYWJlbCA9ICJEb3R0ZWQgbGluZXMgc2hvdyBhdmVyYWdlXG4gY3VycmVudCBoZWlnaHQgb2YgQ2FuYWRpYW5zIiksIHNpemUgPSAzLjUsIGNvbG91ciA9ICJibGFjayIpCgogIApiYXNlX3Bsb3RfMgoKYmxhbmsgPC0gZ2dwbG90KCkgKwogIHRoZW1lX2ZpdmV0aGlydHllaWdodCgpIAoKbGlicmFyeShjb3dwbG90KQoKdGl0bGUgPC0gZ2dkcmF3KGJsYW5rKSArCiAgZHJhd19sYWJlbCgKICAgICIgICBBcmUgdm9sbGV5IGJhbGwgcGxheWVycyBnZXR0aW5nIHNob3J0ZXI/IFNpbXBzb24ncyBQYXJhZG94IG9uIHRoZSBiZWFjaC4iLAogICAgZm9udGZhY2UgPSAnYm9sZCcsCiAgICB4ID0gMCwKICAgIGhqdXN0ID0gMAogICkgCgoKc3RlcDEgPC0gY293cGxvdDo6cGxvdF9ncmlkKG5vX2dlbmRlciwgYmxhbmspCmZpbmFsIDwtIGNvd3Bsb3Q6OnBsb3RfZ3JpZCh0aXRsZSwgc3RlcDEsIGJhc2VfcGxvdF8yLCByZWxfd2lkdGhzID0gYygxLDEsMiksIG5yb3c9MywgcmVsX2hlaWdodHMgPSBjKDEsIDMsIDUpKQoKCnNhdmVfcGxvdCgiY29tYm9fdmJfcGxvdC5wbmciLCBmaW5hbCwgYmFzZV93aWR0aCA9IDEwLCBiYXNlX2hlaWdodCA9IDgpCgpgYGAKCiMjIDEwLiBTaGFyZSB0aGUgcGxvdCEKClNoYXJlIHRoZSBwbG90IGFuZCBsaW5rIHRvIHlvdXIgY29tbWVudGVkIGNvZGUgd2l0aCBhbGwgeW91ciB3b3JraW5nIGluICNwb3J0Zm9saW8tYnVpbGRpbmcgd2l0aCBhIDHigJMyIHNlbnRlbmNlIGV4cGxhbmF0aW9uIGJ5IHRoZSBlbmQgb2YgVHVlc2RheSBNYXkgMTkgKGJvbnVzIGlmIHlvdSBzaGFyZSBpdCBvbiBUd2l0dGVyIHdpdGggI1RpZHlUdWVzZGF5KS4gT3VyIElTU0MgVHdlZXBzIGFyZSBvbiBbdGhpcyBsaXN0XShodHRwczovL3R3aXR0ZXIuY29tL2kvbGlzdHMvMTI1ODQ1NTYyMDExMTUxNTY0OC9tZW1iZXJzKS4gTWVzc2FnZSBtZSBpZiB5b3Ugd2FudCB0byBiZSBhZGRlZCEKCgpUaGFua3MgZXZlcnlvbmUhIAoKClBsZWFzZSBtYWtlIHN1cmUgeW91IGZpbGwgb3V0IHRoZSBbd2Vla2x5IGNoZWNrLWluXShodHRwczovL2Zvcm1zLm9mZmljZS5jb20vUGFnZXMvUmVzcG9uc2VQYWdlLmFzcHg/aWQ9SnNLcWVBTXZUVXVRTjdSdFZzVlNFT0tIVVUzU3pBSkpobU9LakpoRFdFcFVNRmhYVVZFNFdVTkJOek5LVUVoQ05EQkJTMVF3TjB0U05DNHUpIGJ5IFRodXJzZGF5IGF0IDExOjMwIHBtIEVULiA=